// @ts-ignore
import iotApi from '@ohos.serialhelper'

const TemperatureAndHumidity = [0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC5, 0xE9] // 温湿度
const CO2 = [0x04, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0x9F] // 二氧化碳
const Illuminance = [0x05, 0x03, 0x00, 0x06, 0x00, 0x01, 0x65, 0x8F] // 光照度
const PH = [0x02, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x3A] // PH
const ControlOpen = [0xFE, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x98, 0x35] // 控制器1 打开
const ControlClose = [0xFE, 0x05, 0x00, 0x00,  0x00, 0x00, 0xD9, 0xC5] // 控制器1 关闭
const CheckControlState = [0xFE, 0x01, 0x00, 0x00, 0x00, 0x04, 0x29, 0xC6] // 查询继电器状态

const TemperatureAndHumidityCheck = '3,3'
const CO2Check = '4,3'
const IlluminanceCheck = '5,3'
const PHCheck = '2,3'
const RelayCheck = '254,1,1'

enum DeviceState {
    OPEN_FAIL = -3,
    CLOSE_FAIL = -2,
    CLOSED = -1, // 设备已关闭
    CLOSE_SUC = 0,
    OPEN_SUC = 1,
    OPENED = 2 // 设备已打开
}
enum ControlDeviceState {
    SUCCESS = 1,
    FAIL = 0,
    NOT_DEVICE = -1 // 设备已打开
}

enum RelayState {
    OPEN = 1,
    CLOSE = 0,
    UNKNOW = -1
}

export class SensorInfo {
    devFd: number = -1
    timeIndex: number = 0
    timeId: number
    public temperature: number=5 // 温度
    public humidity: number // 湿度
    public co2: number // 二氧化碳
    public illuminance: number // 光照度
    public ph: number // PH值
    public conductivity: number // 电导率
    public relayValue: string // 继电器状态-二进制字符串
    sendAndRecvDataIng: boolean = false // 发送接收标记位

    constructor() {
    }

    // 获取传感器数据
    getSensorInfo() {
        return {
            temperature: this.temperature,
            humidity: this.humidity,
            co2: this.co2,
            illuminance: this.illuminance,
            ph: this.ph,
            conductivity: this.conductivity,
            relayValue: this.relayValue
        }
    }

    // 打开设备
    openDevice() {
        console.log('SensorInfo start openDevice')
        return new Promise((resolve, reject) => {
            if (this.devFd > 0) {
                resolve(DeviceState.OPENED)
            } else {
                console.log('sensorInfo start openDevice')
                iotApi.openSerial('/dev/ttyUSB0')
                    .then((fd) => {
                        this.devFd = fd
                        if (this.devFd > 0) {
                            console.log('sensorInfo openSerial suc')
                            iotApi.setOptions(this.devFd, 4800, 8, 0, 1).then((setOptionsRet) => {
                                console.log('sensorInfo setOptionsRet:' + setOptionsRet)
                            }).catch((error) => {
                                console.error('sensorInfo setOptionsRet catch error:' + JSON.stringify(error))
                            })

                            if (!this.timeId) {
                                this.setSchedule()
                            }
                            resolve(DeviceState.OPEN_SUC)
                        } else {
                            console.log('sensorInfo openSerial fail')
                            resolve(DeviceState.OPEN_FAIL)
                        }
                    })
                    .catch((error) => {
                        console.log('sensorInfo openDevice catch error:' + JSON.stringify(error))
                        reject(error)
                    })

            }
        });
    }

    // 关闭设备
    closeDevice() {
        return new Promise((resolve, reject) => {
            if (this.devFd > 0) {
                iotApi.closeSerial(this.devFd).then((result) => {
                    this.devFd = -1
                    console.log('sensorInfo closeDevice suc result:' + result)
                    resolve(DeviceState.CLOSE_SUC)
                }).catch((error) => {
                    console.log('sensorInfo closeDevice error:' + JSON.stringify(error))
                    resolve(DeviceState.CLOSE_FAIL)
                })
            } else {
                console.log('sensorInfo closeDevice device alredy close')
                resolve(DeviceState.CLOSED)
            }
        })
    }

    // 查询继电器状态
    checkRelayState() {
        console.log('start checkRelayState')
        let arr: Array<number> = CheckControlState;
        let uint8Arr = new Uint8Array(arr);
        iotApi.sendData(this.devFd, uint8Arr).then((sendDataRet) => {
            console.log('start checkRelayState sendDataRet: ' + sendDataRet)
            if (sendDataRet) {
                iotApi.recvData(this.devFd, 6, 1000).then((recvDataRet) => {
                    recvDataRet = recvDataRet.toString()
                    console.log('sensorInfo checkRelayState recvDataRet: ' + recvDataRet)
                    if (recvDataRet.indexOf(RelayCheck) >= 0) {
                        const resultArr = recvDataRet.split(',')
                        const order = parseInt(resultArr[3])
                        this.relayValue = order.toString(2)
                        console.log('sensorInfo checkRelayState order: ' + this.relayValue)
                    } else {
                        console.error('sensorInfo checkRelayState recvData error:' + recvDataRet)
                    }
                }).catch((error) => {
                    console.error('sensorInfo checkRelayState recvData catch: ' + JSON.stringify(error))
                })
            } else {
                console.log('start checkRelayState not recvData')
            }
        }).catch((error) => {
            console.error('sensorInfo checkRelayState error:' + JSON.stringify(error))
        })
    }

    // 获取查询继电器状态
    getRelayState(index) {
        console.log('start getRelayState')
        return new Promise((resolve, reject) => {
            if(this.devFd > 0) {
                let arr: Array<number> = CheckControlState;
                let uint8Arr = new Uint8Array(arr);
                iotApi.sendData(this.devFd, uint8Arr).then((sendDataRet) => {
                    console.log('start getRelayState sendDataRet: ' + sendDataRet)
                    if (sendDataRet) {
                        iotApi.recvData(this.devFd, 6, 1000).then((recvDataRet) => {
                            recvDataRet = recvDataRet.toString()
                            console.log('sensorInfo getRelayState recvDataRet: ' + recvDataRet)
                            if (recvDataRet.indexOf(RelayCheck) >= 0) {
                                const resultArr = recvDataRet.split(',')
                                const order = parseInt(resultArr[3])
                                this.relayValue = order.toString(2)
                                console.log('sensorInfo getRelayState relayValue: ' + this.relayValue)
                                const bit = this.relayValue.substr(this.relayValue.length - 1 - index, 1)
                                console.log('sensorInfo getRelayState current bit: ' + bit)
                                if (parseInt(bit) != 0) {
                                    resolve(RelayState.OPEN)
                                } else {
                                    resolve(RelayState.CLOSE)
                                }
                            } else {
                                console.error('sensorInfo getRelayState recvData error:' + recvDataRet)
                                resolve(RelayState.UNKNOW)
                            }
                        }).catch((error) => {
                            console.error('sensorInfo getRelayState recvData catch: ' + JSON.stringify(error))
                            resolve(RelayState.UNKNOW)
                        })
                    } else {
                        console.log('start getRelayState not recvData')
                    }

                }).catch((error) => {
                    console.error('sensorInfo getRelayState error:' + JSON.stringify(error))
                    resolve(RelayState.UNKNOW)
                })
            } else {
                resolve(RelayState.UNKNOW)
            }
        })
    }

    // 控制-打开浇水
    openWater() {
        return new Promise((resolve, reject) => {
            if(this.devFd > 0) {
                let arr: Array<number> = ControlOpen;
                let uint8Arr = new Uint8Array(arr);
                if (this.sendAndRecvDataIng) {
                    console.log(' openWater sleep 100')
                    this.sleep(100)
                }
                iotApi.sendData(this.devFd, uint8Arr).then((result) => {
                    console.log(' sensorInfo openWater sendData suc: ' + result)
                    if (result) {
                        resolve(ControlDeviceState.SUCCESS)
                    } else {
                        resolve(ControlDeviceState.FAIL)
                    }
                }).catch((error) => {
                    console.error(' sensorInfo openWater error:' + JSON.stringify(error))
                    resolve(ControlDeviceState.FAIL)
                })

            } else {
                resolve(ControlDeviceState.NOT_DEVICE)
            }

        })
    }

    // 控制-关闭浇水
    closeWater() {
        return new Promise((resolve, reject) => {
            if(this.devFd > 0) {
                let arr: Array<number> = ControlClose;
                let uint8Arr = new Uint8Array(arr);
                if (this.sendAndRecvDataIng) {
                    console.log(' openWater sleep 100')
                    this.sleep(100)
                }
                iotApi.sendData(this.devFd, uint8Arr).then((result) => {
                    console.log(' sensorInfo closeWater sendData suc: ' + result)
                    if (result) {
                        resolve(ControlDeviceState.SUCCESS)
                    } else {
                        resolve(ControlDeviceState.FAIL)
                    }
                }).catch((error) => {
                    console.error(' sensorInfo closeWater error:' + JSON.stringify(error))
                    resolve(ControlDeviceState.FAIL)
                })
            } else {
                resolve(ControlDeviceState.NOT_DEVICE)
            }

        })
    }

    // 启动定时器查询传感器数据
    setSchedule() {
       // this.timeIndex = 1
       // this.getTemperatureAndHumidityData()
        this.timeId = setInterval(() => {
            if (this.timeIndex == 0) {
                this.timeIndex = 1
                this.getTemperatureAndHumidityData()
            } else if (this.timeIndex == 1) {
                this.timeIndex = 2
                this.getCo2Data()
            } else if (this.timeIndex == 2) {
                this.timeIndex = 3
                this.getIlluminanceData()
            } else if (this.timeIndex == 3) {
                this.timeIndex = 0
                this.getPhData()
            }
            console.log(`sensorInfo temperature=${this.temperature} humidity=${this.humidity} co2=${this.co2} illuminance=${this.illuminance} ph=${this.ph} conductivity=${this.conductivity}`)
        }, 2500)
    }

    cancelSchedule() {
        if (this.timeId) {
            clearInterval(this.timeId)
        }
    }

    // 获取温湿度数据
    getTemperatureAndHumidityData() {
        console.log('sensorInfo start getTemperatureAndHumidityData')
        let arr: Array<number> = TemperatureAndHumidity;
        let uint8Arr = new Uint8Array(arr);
        this.sendAndRecvDataIng = true
        iotApi.sendData(this.devFd, uint8Arr).then((sendDataRet) => {
            if (sendDataRet) {
                iotApi.recvData(this.devFd, 9, 1000).then((recvDataRet) => {
                    this.sendAndRecvDataIng = false
                    recvDataRet = recvDataRet.toString()
                    if (recvDataRet.indexOf(TemperatureAndHumidityCheck) >= 0) {
                        console.log('sensorInfo formatTemperatureAndHumidity: ' + recvDataRet)
                        this.formatTemperatureAndHumidity(recvDataRet)
                    } else {
                        console.error('sensorInfo getTemperatureAndHumidityData recvData error:' + recvDataRet)
                    }
                }).catch((error) => {
                    this.sendAndRecvDataIng = false
                    console.error('sensorInfo getTemperatureAndHumidityData recvData catch: ' + JSON.stringify(error))
                })
            }
        }).catch((error) => {
            console.error('sensorInfo getTemperatureAndHumidityData sendData catch: ' + JSON.stringify(error))
        })

    }

    // 转换温湿度数据格式
    formatTemperatureAndHumidity(result) {
        const resultArr = result.split(',')
        const humidity_high_order = parseInt(resultArr[3])
        const humidity_low_order = parseInt(resultArr[4])
        this.humidity = (humidity_high_order * 256 + humidity_low_order) / 10

        const temperature_high_order = parseInt(resultArr[5])
        const temperature_low_order = parseInt(resultArr[6])

        if(temperature_high_order * 256 + temperature_low_order  > parseInt('0x8000', 16))
        {
            this.temperature = (parseInt('0xffff', 16) - (temperature_high_order * 256 + temperature_low_order) + 1) / 10
        }
        else
        {
            this.temperature = (temperature_high_order * 256 + temperature_low_order) / 10
        }
    }

    // 获取二氧化碳数据
    getCo2Data() {
        console.log('sensorInfo start getCo2Data')
        let arr: Array<number> = CO2;
        let uint8Arr = new Uint8Array(arr);
        this.sendAndRecvDataIng = true
        iotApi.sendData(this.devFd, uint8Arr).then((sendDataRet) => {
            if (sendDataRet) {
                iotApi.recvData(this.devFd, 7, 1000).then((recvDataRet) => {
                    this.sendAndRecvDataIng = false
                    recvDataRet = recvDataRet.toString()
                    if (recvDataRet.indexOf(CO2Check) >= 0) {
                        console.log('sensorInfo formatCo2:' + recvDataRet)
                        this.formatCo2(recvDataRet)
                    } else {
                        console.error('sensorInfo getCo2Data recvData error:' + recvDataRet)
                    }
                }).catch((error) => {
                    this.sendAndRecvDataIng = false
                    console.error('sensorInfo getCo2Data recvData catch: ' + JSON.stringify(error))
                })
            }
        }).catch((error) => {
            console.error('sensorInfo getCo2Data sendData catch: ' + JSON.stringify(error))
        })

    }

    // 转换二氧化碳数据格式 单位：ppm
    formatCo2(result) {
        const resultArr = result.split(',')
        const co2_high_order = parseInt(resultArr[3])
        const co2_low_order = parseInt(resultArr[4])
        this.co2 = co2_high_order * 256 + co2_low_order
    }

    // 获取光照度值数据
    getIlluminanceData() {
        console.log('sensorInfo start getIlluminanceData')
        let arr: Array<number> = Illuminance;
        let uint8Arr = new Uint8Array(arr);
        this.sendAndRecvDataIng = true
        iotApi.sendData(this.devFd, uint8Arr).then((sendDataRet) => {
            if (sendDataRet) {
                this.sendAndRecvDataIng = false
                iotApi.recvData(this.devFd, 7, 1000).then((recvDataRet) => {
                    recvDataRet = recvDataRet.toString()
                    if (recvDataRet.indexOf(IlluminanceCheck) >= 0) {
                        console.log('sensorInfo formatIlluminance result:' + recvDataRet)
                        this.formatIlluminance(recvDataRet)
                    } else {
                        console.error('sensorInfo getIlluminanceData recvData error:' + recvDataRet)
                    }
                }).catch((error) => {
                    this.sendAndRecvDataIng = false
                    console.error('sensorInfo getIlluminanceData recvData catch: ' + JSON.stringify(error))
                })

            }
        }).catch((error) => {
            console.error('sensorInfo getIlluminanceData sendData catch: ' + JSON.stringify(error))
        })
    }

    // 转换光照度值数据格式 单位：Lux
    formatIlluminance(result) {
        const resultArr = result.split(',')
        const illuminance_high_order = parseInt(resultArr[3])
        const illuminance_low_order = parseInt(resultArr[4])
        this.illuminance = illuminance_high_order * 256 + illuminance_low_order
    }

    // 获取PH数据
    getPhData() {
        console.log('sensorInfo start getPhData')
        let arr: Array<number> = PH;
        let uint8Arr = new Uint8Array(arr);
        this.sendAndRecvDataIng = true
        iotApi.sendData(this.devFd, uint8Arr).then((sendDataRet) => {
            if (sendDataRet) {
                iotApi.recvData(this.devFd, 13, 1000).then((recvDataRet) => {
                    this.sendAndRecvDataIng = false
                    recvDataRet = recvDataRet.toString()
                    if (recvDataRet.indexOf(PHCheck) >= 0) {
                        console.log('sensorInfo formatPh result:' + recvDataRet)
                        this.formatPh(recvDataRet)
                    } else {
                        console.error('sensorInfo getPhData recvData error:' + recvDataRet)
                    }
                }).catch((error) => {
                    this.sendAndRecvDataIng = false
                    console.error('sensorInfo getIlluminanceData recvData catch: ' + JSON.stringify(error))
                })
            }
        }).catch((error) => {
            console.error('sensorInfo getIlluminanceData sendData catch: ' + JSON.stringify(error))
        })
    }

    // 转换PH数据格式 单位：μS/cm
    formatPh(result) {
        const resultArr = result.split(',')
        const ph_high_order = parseInt(resultArr[9])
        const ph_low_order = parseInt(resultArr[10])
        this.ph = (ph_high_order * 256 + ph_low_order) / 10

        const conductivity_high_order = parseInt(resultArr[7])
        const conductivity_low_order = parseInt(resultArr[8])
        this.conductivity = conductivity_high_order * 256 + conductivity_low_order
    }

    sleep(delay) {
        const start = (new Date()).getTime();
        while ((new Date()).getTime() - start < delay) {
            // 使用  continue 实现；
            continue;
        }
    }

}